(define (deriv e x)
  (cond ((number? e) 0)
         ((variable? e) (if (same-variable? e x) 1 0))
         ((sum? e) (make-sum (deriv (addend e) x)
                             (deriv (augend e) x)))
         ((product? e) (make-sum (make-product (multiplier e)
                                               (deriv (multiplicand e) x))
                                 (make-product (deriv (multiplier e) x)
                                               (multiplicand e))))
         ((exponentitation? e x) (make-product
                                  (make-product (exponent e)
                                                (make-exponentitation (base e x)s
         (else
          (display "error"))))

(define (variable? e)
  (symbol? e))

(define (same-variable? e x)
  (and (symbol? e) (symbol? x) (eq? e x)))

(define (sum? e)
  (eq? (car e) '+))

(define (addend e)
  (cadr e))

(define (augend e)
  (caddr e))

(define (make-sum e1 e2)
  (cond ((=number? e1 0) e2)
        ((=number? e2 0) e1)
        ((and (number? e1) (number? e2)) (+ e1 e2))
        (else (list '+ e1 e2))))

(define (=number? e v)
  (and (number? e) (= e v)))

(define (product? e)
  (eq? (car e) '*))

(define (multiplier e)
  (cadr e))

(define (multiplicand e)
  (caddr e))

(define (make-product e1 e2)
  (cond ((or (=number? e1 0) (=number? e2 0))
         0)
        ((=number? e1 1) e2)
        ((=number? e2 1) e1)
        ((and (number? e1) (number? e2)) (* e1 e2))
        (else (list '* e1 e2))))

(deriv '(+ x 3) 'x)
(deriv '(* x y) 'x)
(deriv '(* (* x y) (+ x 3)) 'x)









